package cn.wetcland.es.service.impl;

import cn.wetcland.es.config.exception.CustomerException;
import cn.wetcland.es.config.exception.CustomerExceptionTypeEnum;
import cn.wetcland.es.domain.*;
import cn.wetcland.es.dto.TaskDoDTO;
import cn.wetcland.es.dto.TaskDoListItemDTO;
import cn.wetcland.es.mapper.*;
import cn.wetcland.es.utils.MyAssert;
import cn.wetcland.es.vo.EvaluationNodeVO;
import cn.wetcland.es.vo.TaskAndStatusListItemVO;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import cn.wetcland.es.service.EsTaskService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.servlet.http.HttpSession;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
* @author Wetcland
* @description 针对表【es_task】的数据库操作Service实现
* @createDate 2023-04-29 17:04:49
*/
@Service
public class EsTaskServiceImpl extends ServiceImpl<EsTaskMapper, EsTask> implements EsTaskService{

    @Resource
    private EsTaskMapper taskMapper;

    @Resource
    private EsNodeMapper nodeMapper;

    @Resource
    private EsNodeItemMapper nodeItemMapper;

    @Resource
    private EsStudentTaskMapper studentTaskMapper;

    @Resource
    private EsTeacherTaskMapper teacherTaskMapper;

    @Override
    public List<List<TaskAndStatusListItemVO>> getAllTask(HttpSession session) {
        Object target = session.getAttribute("target");
        List<List<TaskAndStatusListItemVO>> res = new ArrayList<>();
        List<TaskAndStatusListItemVO> esTasks = null;
        if (target instanceof EsStudent) {
            EsStudent student = (EsStudent) target;
            esTasks = taskMapper.selectStudentTaskAndStatusList(student.getEsStudentId());
        } else if (target instanceof EsTeacher) {
            EsTeacher teacher = (EsTeacher) target;
            esTasks = taskMapper.selectTeacherTaskAndStatusList(teacher.getEsTeacherId());
        }
        int f = 0;
        if (esTasks.size() == 0) {
            return res;
        }
        for (int i = 0; i < (esTasks.size()%3==0?esTasks.size()/3:esTasks.size()/3 + 1); i++) {
            List<TaskAndStatusListItemVO> t = new ArrayList<>();
            for (int j = 0; j < 3; j++) {
                int index = i * 3 + j;
                if (index < esTasks.size()) {
                    t.add(esTasks.get(index));
                }
            }
            res.add(t);
        }
        return res;
    }

    @Override
    public List<EvaluationNodeVO> genEvalTableByTaskId(Long taskId) {
        MyAssert.notNull(taskId, "任务ID不能为空");
        EsTask esTask = taskMapper.selectById(taskId);
        MyAssert.notNull(esTask, "该任务不存在");
        List<EvaluationNodeVO> res = new ArrayList<>();
        List<EsNode> esNodes = nodeMapper.selectList(new QueryWrapper<EsNode>().eq("es_node_task_id", taskId));
        for (EsNode esNode : esNodes) {
            List<EsNodeItem> esNodeItems = nodeItemMapper.selectList(new QueryWrapper<EsNodeItem>().eq("es_node_item_node_id", esNode.getEsNodeId()));
            EvaluationNodeVO evaluationNodeVO = new EvaluationNodeVO();
            evaluationNodeVO.setNodeType(getNodeTypeString(esNode.getEsNodeType()));
            evaluationNodeVO.setNodeTech(esNode.getEsNodeTech());
            int rowspanCount = 0;
            Set<Integer> set = new HashSet<>();
            for (EsNodeItem esNodeItem : esNodeItems) {
                rowspanCount++;
                set.add(esNodeItem.getEsNodeItemType());
            }
            evaluationNodeVO.setRowSpanCount(rowspanCount);
            List<EvaluationNodeVO.NodeTypeItem> nodeTypeItems = new ArrayList<>();
            for (Integer v : set) {
                EvaluationNodeVO.NodeTypeItem nt = new EvaluationNodeVO.NodeTypeItem();
                if (v == 1) {
                    // 知识
                    List<EsNodeItem> collect = esNodeItems.stream().filter(vv -> vv.getEsNodeItemType() == 1).collect(Collectors.toList());
                    nt.setNodeTypeName("知识");
                    nt.setNodeItems(toNodeItem(collect));
                } else if (v == 2) {
                    // 能力
                    List<EsNodeItem> collect = esNodeItems.stream().filter(vv -> vv.getEsNodeItemType() == 2).collect(Collectors.toList());
                    nt.setNodeTypeName("能力");
                    nt.setNodeItems(toNodeItem(collect));
                } else if (v == 3) {
                    // 素养
                    List<EsNodeItem> collect = esNodeItems.stream().filter(vv -> vv.getEsNodeItemType() == 3).collect(Collectors.toList());
                    nt.setNodeTypeName("素养");
                    nt.setNodeItems(toNodeItem(collect));
                }
                nodeTypeItems.add(nt);
            }
            evaluationNodeVO.setNodeTypeItems(nodeTypeItems);
            res.add(evaluationNodeVO);
        }
        return res;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void doTask(TaskDoDTO doDTO, HttpSession session) {
        List<TaskDoListItemDTO> taskDoListItemDTOS = parseTaskItemList(doDTO);
        int count = taskMapper.selectNodeItemCount(doDTO.getTaskId());
        MyAssert.isTrue(taskDoListItemDTOS.size() == count, "评价表提交存在遗漏");
        List<Long> longs = new ArrayList<>();
        for (TaskDoListItemDTO taskDoListItemDTO : taskDoListItemDTOS) {
            longs.add(taskDoListItemDTO.getNodeItemId());
        }
        Integer selectCount = nodeItemMapper.selectCount(new QueryWrapper<EsNodeItem>().in("es_node_item_id", longs));
        MyAssert.isTrue(selectCount == count, "评价表提交存在遗漏-错误");
        Object target = session.getAttribute("target");
        if (target instanceof EsStudent) {
            EsStudent esStudent = ((EsStudent) target);
            insertStudentTask(esStudent.getEsStudentId(), doDTO.getTaskId(), taskDoListItemDTOS);
        } else if (target instanceof EsTeacher) {
            EsTeacher teacher = (EsTeacher) target;
            insertTeacherTask(teacher.getEsTeacherId(), doDTO.getTaskId(), taskDoListItemDTOS);
        }
    }

    public void insertStudentTask(Long studentId, Long taskId, List<TaskDoListItemDTO> list) {
        // 可重复提交：插入之前把之前的记录删除
        studentTaskMapper.delete(new QueryWrapper<EsStudentTask>()
                .eq("es_student_id", studentId)
                .eq("es_task_id", taskId)
        );
        for (TaskDoListItemDTO itemDTO : list) {
            EsStudentTask esStudentTask = new EsStudentTask();
            esStudentTask.setEsStudentId(studentId);
            esStudentTask.setEsTaskId(taskId);
            esStudentTask.setEsNodeItemId(itemDTO.getNodeItemId());
            esStudentTask.setScore(itemDTO.getScore());
            studentTaskMapper.insert(esStudentTask);
        }
    }

    public void insertTeacherTask(Long teacherId, Long taskId, List<TaskDoListItemDTO> list) {
        // 可重复提交：插入之前把之前的记录删除
        teacherTaskMapper.delete(new QueryWrapper<EsTeacherTask>()
                .eq("es_teacher_id", teacherId)
                .eq("es_task_id", taskId)
        );
        for (TaskDoListItemDTO itemDTO : list) {
            EsTeacherTask esTeacherTask = new EsTeacherTask();
            esTeacherTask.setEsTeacherId(teacherId);
            esTeacherTask.setEsTaskId(taskId);
            esTeacherTask.setEsNodeItemId(itemDTO.getNodeItemId());
            esTeacherTask.setScore(itemDTO.getScore());
            teacherTaskMapper.insert(esTeacherTask);
        }
    }

    public List<TaskDoListItemDTO> parseTaskItemList(TaskDoDTO doDTO) {
        List<TaskDoListItemDTO> res = new ArrayList<>();
        for (String doItem : doDTO.getDoItems()) {
            try {
                String[] split = doItem.split("-");
                TaskDoListItemDTO itemDTO = new TaskDoListItemDTO();
                itemDTO.setNodeItemId(Long.valueOf(split[0]));
                itemDTO.setScore(Integer.valueOf(split[1]));
                res.add(itemDTO);
            } catch (Exception e) {
                throw new CustomerException(CustomerExceptionTypeEnum.ASSERT_WARNING, "评价表提交解析失败");
            }
        }
        return res;
    }

    public String getNodeTypeString(int type) {
        if (type == 1) {
            return "导测";
        } else if (type == 2) {
            return "前测";
        } else if (type == 3) {
            return "后测";
        }
        return null;
    }

    public List<EvaluationNodeVO.NodeItem> toNodeItem(List<EsNodeItem> list) {
        List<EvaluationNodeVO.NodeItem> res = new ArrayList<>();
        for (EsNodeItem esNodeItem : list) {
            EvaluationNodeVO.NodeItem n = new EvaluationNodeVO.NodeItem();
            n.setNodeItemId(esNodeItem.getEsNodeItemId());
            n.setNodeItemContent(esNodeItem.getEsNodeItemContent());
            n.setScoreMaxLimit(esNodeItem.getEsNodeItemScore());
            res.add(n);
        }
        return res;
    }

}




